package com.zrwl.poscloud.xo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zrwl.poscloud.base.entity.Company;
import com.zrwl.poscloud.base.entity.CompanyDictData;
import com.zrwl.poscloud.base.entity.SysDictData;
//import com.zrwl.poscloud.base.enums.CompanyServerBusinessType;
import com.zrwl.poscloud.base.enums.EStatus;
import com.zrwl.poscloud.base.superI.SuperServiceImpl;
import com.zrwl.poscloud.commons.holder.RequestHolder;
import com.zrwl.poscloud.commons.utils.JsonUtils;
import com.zrwl.poscloud.commons.utils.RedisUtil;
import com.zrwl.poscloud.commons.utils.ResultUtil;
import com.zrwl.poscloud.commons.utils.StringUtils;
import com.zrwl.poscloud.xo.global.MessageConf;
import com.zrwl.poscloud.xo.global.RedisConf;
import com.zrwl.poscloud.xo.global.SQLConf;
import com.zrwl.poscloud.xo.global.SysConf;
import com.zrwl.poscloud.xo.mapper.CompanyDictDataMapper;
import com.zrwl.poscloud.xo.service.AdminService;
import com.zrwl.poscloud.xo.service.CompanyDictDataService;
import com.zrwl.poscloud.xo.service.CompanyService;
import com.zrwl.poscloud.xo.service.SysDictDataService;
import com.zrwl.poscloud.xo.vo.CompanyDictDataVO;
//import com.zrwl.poscloud.xo.vo.ServerSyncRecordVO;
import com.zrwl.poscloud.xo.vo.SysDictDataVO;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 商户字典数据 服务实现类
 *
 * @author 刘思童 AutoGenerate
 * @date 2021-04-26
 */
@Service
public class CompanyDictDataServiceImpl extends SuperServiceImpl<CompanyDictDataMapper, CompanyDictData> implements CompanyDictDataService {

    @Autowired
    private CompanyDictDataService companyDictDataService;
    @Autowired
    private SysDictDataService sysDictDataService;
    @Autowired
    private AdminService adminService;
//    @Autowired
//    private ModelDictDataService modelDictDataService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    RedisUtil redisUtil;
//    @Autowired
//    private ServerSyncRecordService serverSyncRecordService;

    @Resource
    private CompanyDictDataMapper companyDictDataMapper;

    @Override
    public IPage<CompanyDictData> getPageList(CompanyDictDataVO companyDictDataVO) {
        QueryWrapper<CompanyDictData> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(companyDictDataVO.getKeyword()) && !StringUtils.isEmpty(companyDictDataVO.getKeyword().trim())) {
            queryWrapper.like("dict_label", companyDictDataVO.getKeyword().trim());
        }
        if (companyDictDataVO.getModelDictTypeUid() != null && companyDictDataVO.getModelDictTypeUid() != "") {
            queryWrapper.eq("model_dict_type_uid", companyDictDataVO.getModelDictTypeUid());
        }
        if (companyDictDataVO.getDictType() != null && companyDictDataVO.getDictType() != "") {
            queryWrapper.eq("dict_type", companyDictDataVO.getDictType());
        }
        Page<CompanyDictData> page = new Page<>();
        page.setCurrent(companyDictDataVO.getCurrentPage());
        page.setSize(companyDictDataVO.getPageSize());
        if (companyDictDataVO.getCompanyUid() != null) {
            queryWrapper.eq("company_uid", companyDictDataVO.getCompanyUid());
        } else {
            queryWrapper.eq("1", "2");
        }
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        IPage<CompanyDictData> pageList = companyDictDataService.page(page, queryWrapper);
        List<CompanyDictData> list = pageList.getRecords();
        pageList.setRecords(list);
        return pageList;
    }

    @Override
    public List<CompanyDictData> getAllList(CompanyDictDataVO companyDictDataVO) {
        HttpServletRequest request = RequestHolder.getRequest();
        String ownerUid = request.getAttribute(SysConf.OWNER_UID).toString();
        QueryWrapper<CompanyDictData> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        if (ownerUid != null) {
            queryWrapper.eq("company_uid", ownerUid);
        } else {
            queryWrapper.eq("1", "2");
        }
        queryWrapper.orderByAsc(SQLConf.CREATE_TIME);
        List<CompanyDictData> list = companyDictDataService.list(queryWrapper);
        return list;
    }

    @Override
    public String add(CompanyDictDataVO companyDictDataVO) {
        CompanyDictData entity = new CompanyDictData();
        Company company = companyService.getById(companyDictDataVO.getCompanyUid());
        BeanUtils.copyProperties(companyDictDataVO, entity, SysConf.STATUS);
        if (companyDictDataIsItEffective(companyDictDataVO) != null) {
            return ResultUtil.errorWithMessage("重复的数据添加!");
        }
        entity.setIsFromModel(0);
        entity.setCreateByUid(adminService.getMe().getUid());
        entity.setUpdateByUid(adminService.getMe().getUid());
        entity.setDictValue(getDictValue(entity));
        entity.insert();
        companyDictDataVO.setUid(entity.getUid());
        Set<String> keys = redisUtil.keys(company.getUid()+ SysConf.REDIS_SEGMENTATION + company.getCompanyDictTypeUid() + SysConf.REDIS_SEGMENTATION + "*");
        redisUtil.delete(keys);
        return ResultUtil.successWithMessage(MessageConf.INSERT_SUCCESS);
    }

    @Override
    public String edit(CompanyDictDataVO companyDictDataVO) {

        CompanyDictData companyDictData = companyDictDataIsItEffective(companyDictDataVO);
        if (companyDictData != null && !companyDictData.getUid().equals(companyDictDataVO.getUid())) {
            return ResultUtil.errorWithMessage("重复的数据添加!");
        }
        CompanyDictData entity = companyDictDataService.getById(companyDictDataVO.getUid());
        Company company = companyService.getById(entity.getCompanyUid());
        BeanUtils.copyProperties(companyDictDataVO, entity);
        entity.setUpdateByUid(adminService.getMe().getUid());
        entity.setIsFromModel(0);
        //entity.setUpdateTime//已通过填充实现，后续可删除(new Date());
        entity.setDictValue(getDictValue(entity));
        entity.updateById();
        Set<String> keys = redisUtil.keys(company.getUid()+ SysConf.REDIS_SEGMENTATION + company.getCompanyDictTypeUid() + SysConf.REDIS_SEGMENTATION + "*");
        redisUtil.delete(keys);
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    public String delete(CompanyDictDataVO companyDictDataVO) {

        CompanyDictData entity = companyDictDataService.getById(companyDictDataVO.getUid());
        Company company = companyService.getById(entity.getCompanyUid());
        entity.setStatus(EStatus.DISABLED);
        entity.setUpdateByUid(adminService.getMe().getUid());
        //entity.setUpdateTime//已通过填充实现，后续可删除(new Date());
        entity.updateById();
        Set<String> keys = redisUtil.keys(company.getUid()+ SysConf.REDIS_SEGMENTATION + company.getCompanyDictTypeUid() + SysConf.REDIS_SEGMENTATION + "*");
        redisUtil.delete(keys);
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    public String deleteBatchCompanyDictData(List<CompanyDictDataVO> companyDictDataVOList, Company company) {
        if (companyDictDataVOList.size() <= 0) {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }
        List<String> uids = new ArrayList<>();
        companyDictDataVOList.forEach(item -> {
            uids.add(item.getUid());
        });
        Collection<CompanyDictData> companyDictDataList = companyDictDataService.listByIds(uids);
        companyDictDataList.forEach(item -> {
            item.setStatus(EStatus.FREEZE);
//            item.setUpdateTime(new Date());
            item.setUpdateByUid(adminService.getMe().getUid());
        });
        Boolean check = companyDictDataService.updateBatchById(companyDictDataList);
        if (check) {
            Set<String> keys = redisUtil.keys(company.getUid()+ SysConf.REDIS_SEGMENTATION + company.getCompanyDictTypeUid() + SysConf.REDIS_SEGMENTATION + "*");
            redisUtil.delete(keys);
            return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
        } else {
            return ResultUtil.errorWithMessage(MessageConf.UPDATE_SUCCESS);
        }
    }

    @Override
    public List<SysDictDataVO> getCompanyDictList() throws Exception {
        HttpServletRequest request = RequestHolder.getRequest();
        String ownerUid = request.getAttribute(SysConf.OWNER_UID).toString();
        if (ownerUid == null) {
            throw new RuntimeException("当前用户异常");
        }
        List<SysDictDataVO> sysDictDataList = companyDictDataMapper.getCompanyDictList(companyService.getById(ownerUid).getCompanyDictTypeUid());
        return sysDictDataList;
    }

//    @Override
//    @Transactional
//    public String copyModelCompanyDictData(CompanyDictDataVO companyDictDataVO) {//目前此方法只在云端调用一次
//        List<ModelDictData> modelDictDataList = modelDictDataService.getCopyList(companyDictDataVO);
//        String myUid = adminService.getMe().getUid();
//        Company company = companyService.getById(companyDictDataVO.getCompanyUid());
//        UpdateWrapper<CompanyDictData> updateDictWrapper = new UpdateWrapper<>();
//        updateDictWrapper.set(SQLConf.STATUS, EStatus.DISABLED);
//        updateDictWrapper.set("update_time", new Date());
//        updateDictWrapper.eq("company_uid", companyDictDataVO.getCompanyUid());
//        updateDictWrapper.eq("is_from_model", 1);
//        companyDictDataService.update(updateDictWrapper);
//        //Integer count = getDictValue(companyDictDataVO);//从0开始
//        if (modelDictDataList != null && modelDictDataList.size() != 0) {
//            for (ModelDictData modelDictData : modelDictDataList) {
//                CompanyDictData entity = new CompanyDictData();
//                entity.setModelDictTypeUid(modelDictData.getModelDictTypeUid());
//                entity.setCreateByUid(modelDictData.getCreateByUid());
//                entity.setUpdateByUid(myUid);
//                entity.setDictLabel(modelDictData.getDictLabel());
//                entity.setCompanyUid(companyDictDataVO.getCompanyUid());
//                entity.setSort(modelDictData.getSort());
//                entity.setDictType(modelDictData.getDictType());
//                entity.setIsFromModel(1);
//                if(getDictValue(entity) == -1){
//                    continue;
//                }
//                entity.setDictValue(getDictValue(entity));
//                entity.setRemark(modelDictData.getRemark());
//                entity.setCreateTime(new Date());
//                //entity.setUpdateTime//已通过填充实现，后续可删除(new Date());
//                entity.setStatus(EStatus.ENABLE);
//                entity.insert();
//                /////////////向下同步字典
//                ServerSyncRecordVO serverSyncRecordVORecord = new ServerSyncRecordVO();//加入同步数据
//                serverSyncRecordVORecord.setObject(entity);
//                serverSyncRecordVORecord.setCompanyUid(entity.getCompanyUid());
//                serverSyncRecordVORecord.setSummary(CompanyServerBusinessType.companyDictDataDown.getName());
//                serverSyncRecordVORecord.setName(CompanyServerBusinessType.companyDictDataDown.getName());
//                serverSyncRecordVORecord.setType(CompanyServerBusinessType.companyDictDataDown.getServerBusinessType());
//                serverSyncRecordService.add(serverSyncRecordVORecord);
//                /////////////
//            }
//            Company entity = companyService.getById(companyDictDataVO.getCompanyUid());
//            UpdateWrapper<Company> updateWrapper = new UpdateWrapper<>();
//            updateWrapper.set("company_dict_type_uid", companyDictDataVO.getModelDictTypeUid());
//            updateWrapper.set("update_time", new Date());
//            updateWrapper.eq("uid", entity.getUid());
//            entity.update(updateWrapper);
//            Set<String> keys = redisUtil.keys(company.getUid()+ SysConf.REDIS_SEGMENTATION + company.getCompanyDictTypeUid() + SysConf.REDIS_SEGMENTATION + "*");
//            redisUtil.delete(keys);
//            return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
//        } else return ResultUtil.errorWithMessage(MessageConf.DELETE_FAIL);
//    }

    public CompanyDictData companyDictDataIsItEffective(CompanyDictDataVO companyDictDataVO) {
        QueryWrapper<CompanyDictData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dict_type", companyDictDataVO.getDictType());
        queryWrapper.eq("dict_label", companyDictDataVO.getDictLabel());
        queryWrapper.eq("company_uid", companyDictDataVO.getCompanyUid());
        queryWrapper.eq("model_dict_type_uid", companyDictDataVO.getModelDictTypeUid());
        queryWrapper.ne(SQLConf.STATUS, 0);
        CompanyDictData companyDictData = companyDictDataService.getOne(queryWrapper);
        return companyDictData;
    }

    public int getDictValue(CompanyDictData companyDictData) {
        QueryWrapper<CompanyDictData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("company_uid", companyDictData.getCompanyUid());
        queryWrapper.eq("dict_type", companyDictData.getDictType());
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        queryWrapper.orderByDesc("dict_value");
        queryWrapper.last("limit 0,1");
        CompanyDictData dictData = companyDictDataService.getOne(queryWrapper);
        if (dictData == null) {
            return 0;
        }
        if (StringUtils.isNotEmpty(companyDictData.getUid()) && StringUtils.isNotEmpty(companyDictData.getUid().trim()) && companyDictData.getUid().equals(dictData.getUid())) {
            return -1;
        }
        for (int i = 0; i < dictData.getDictValue(); i++) {
            QueryWrapper<CompanyDictData> q = new QueryWrapper<>();
            q.eq("company_uid", companyDictData.getCompanyUid());
            q.eq("dict_type", companyDictData.getDictType());
            q.eq("dict_value", i);
            q.ne(SQLConf.STATUS, EStatus.DISABLED);
            q.orderByDesc("dict_value");
            CompanyDictData d = companyDictDataService.getOne(q);
            if (d == null) {
                return i;
            }
        }
        return dictData.getDictValue() + 1;
    }

    @Override
    public Map<String, Map> getCompanyAllDictData(CompanyDictDataVO companyDictDataVO) {
        ServletRequestAttributes attribute = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attribute.getRequest();
        String ownerUid = request.getAttribute(SysConf.OWNER_UID).toString();
        String companyAllDictData = redisUtil.get(RedisConf.COMPANY_DICT_DATA + RedisConf.SEGMENTATION + ownerUid);
        if (companyAllDictData == null) {
            QueryWrapper<CompanyDictData> queryWrapperCDD = new QueryWrapper<>();
            queryWrapperCDD.eq("company_uid", companyDictDataVO.getCompanyUid());
            List<CompanyDictData> companyDictDataList = companyDictDataService.list(queryWrapperCDD);
            Map<String, Map> resultMap = new HashMap<>();
            Map<String, SysDictData> companyDictTypeMap = new HashMap<>();
            if (companyDictDataList != null && companyDictDataList.size() > 0) {
                Map<String, List> dicListMap = new HashMap<>();
                resultMap.put("dicDataList", dicListMap);
                for (CompanyDictData items : companyDictDataList) {
                    if (!companyDictTypeMap.containsKey(items.getModelDictTypeUid())) {
                        SysDictData temp = sysDictDataService.getById(items.getModelDictTypeUid());
                        companyDictTypeMap.put(temp.getUid(), temp);
                        List<CompanyDictData> tempList = new ArrayList<>();
                        tempList.add(items);
                        dicListMap.put(temp.getDictValue(), tempList);
                        Map<Integer, String> tempMap = new HashMap<>();
                        tempMap.put(items.getDictValue(), items.getDictLabel());
                        resultMap.put(temp.getDictValue(), tempMap);
                    } else {
                        resultMap.get(companyDictTypeMap.get(items.getModelDictTypeUid()).getDictValue()).put(items.getDictValue(), items.getDictLabel());
                        dicListMap.get(companyDictTypeMap.get(items.getModelDictTypeUid()).getDictValue()).add(items);
                    }
                }
                if (companyDictTypeMap.size() > 0) {
                    List<SysDictData> sysDictDataList = new ArrayList<>();
                    companyDictTypeMap.forEach((k, v) -> {
                        sysDictDataList.add(v);
                    });
                    dicListMap.put("dictTypeList", sysDictDataList);
                }
            }
            redisUtil.setEx(RedisConf.COMPANY_DICT_DATA + SysConf.REDIS_SEGMENTATION + ownerUid, JsonUtils.objectToJson(resultMap), 1, TimeUnit.HOURS);
            return resultMap;
        } else {
            Map<String, Map> resultMap = (Map<String, Map>) JsonUtils.jsonToMap(companyAllDictData, String.class);
            return resultMap;
        }
    }

    @Override
    public Map<String, Map<String, Object>> getListByCompanyDictTypeList(List<String> dictTypeList, String modelDictTypeUid, String companyUid) {
        Company company = companyService.getById(companyUid);
        if (company == null) {
            throw new RuntimeException("该商户不存在");
        }
        Map<String, Map<String, Object>> map = new HashMap<>();
        List<String> tempTypeList = new ArrayList<>();
        dictTypeList.forEach(item -> {
            //从Redis中获取内容
            String jsonResult = redisUtil.get(companyUid + SysConf.REDIS_SEGMENTATION + company.getCompanyDictTypeUid() + SysConf.REDIS_SEGMENTATION + item);
            //判断redis中是否有字典
            if (StringUtils.isNotEmpty(jsonResult)) {
                Map<String,Object> tempMap = JsonUtils.jsonToMap(jsonResult);
                val list = (List<CompanyDictData>) tempMap.get("list");
                if(list.size() >0){
                    map.put(item, tempMap);
                }else {
                    tempTypeList.add(item);
                }
            } else {
                // 如果redis中没有该字典，那么从数据库中查询
                tempTypeList.add(item);
            }
        });
        // 表示数据全部从redis中获取到了，直接返回即可
        if (tempTypeList.size() <= 0) {
            return map;
        }
        QueryWrapper<CompanyDictData> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(SQLConf.DICT_TYPE, dictTypeList);
        queryWrapper.eq("model_dict_type_uid", modelDictTypeUid);
        queryWrapper.eq("company_uid", companyUid);
        queryWrapper.eq(SQLConf.STATUS, EStatus.ENABLE);
        List<CompanyDictData> list = companyDictDataService.list(queryWrapper);
        dictTypeList.forEach(item -> {
            List<CompanyDictData> dictDataList = new ArrayList<>();
            for (CompanyDictData companyDictData : list) {
                if (item.equals(companyDictData.getDictType())) {
                    dictDataList.add(companyDictData);
                }
            }
            Map<String, Object> result = new HashMap<>();
            map.put(item, result);
            result.put(SysConf.LIST, dictDataList);
            map.put(item, result);
            redisUtil.setEx(companyUid + SysConf.REDIS_SEGMENTATION + company.getCompanyDictTypeUid() + SysConf.REDIS_SEGMENTATION + item, JsonUtils.objectToJson(result).toString(), 1, TimeUnit.DAYS);
        });
        return map;
    }

    @Override
    public Map<String, Object> getListByCompanyDictType(String dictType, String companyUid) {
        Company company = companyService.getById(companyUid);
        if (company == null) {
            throw new RuntimeException("该商户不存在");
        }
        //从Redis中获取内容
        String jsonResult = redisUtil.get(companyUid + SysConf.REDIS_SEGMENTATION + company.getCompanyDictTypeUid() + SysConf.REDIS_SEGMENTATION + dictType);
        //判断redis中是否有字典
        if (StringUtils.isNotEmpty(jsonResult)) {
            Map<String, Object> map = JsonUtils.jsonToMap(jsonResult);
            return map;
        }
        QueryWrapper<CompanyDictData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.DICT_TYPE, dictType);
        queryWrapper.eq("model_dict_type_uid", company.getCompanyDictTypeUid());
        queryWrapper.eq("company_uid", companyUid);
        queryWrapper.eq(SQLConf.STATUS, EStatus.ENABLE);
        List<CompanyDictData> list = companyDictDataService.list(queryWrapper);
        Map<String, Object> result = new HashMap<>();
        result.put(SysConf.LIST, list);
        redisUtil.setEx(companyUid + SysConf.REDIS_SEGMENTATION + company.getCompanyDictTypeUid() + SysConf.REDIS_SEGMENTATION + dictType, JsonUtils.objectToJson(result).toString(), 1, TimeUnit.DAYS);
        return result;
    }


    @Override
    public List<CompanyDictData> importList(CompanyDictDataVO companyDictDataVO) {

        List<CompanyDictData> list = new ArrayList<>();
        for (CompanyDictData result : list) {
            String uid = "123";
            String dictLabel = "123";
            int dictValue = 456;
            try {
                CompanyDictData entity = companyDictDataService.getById(uid);
                entity.setCompanyUid(null);
                entity.setModelDictTypeUid(null);
                entity.setDictLabel(dictLabel);
                entity.setDictValue(dictValue);
                entity.setCreateByUid(null);
                entity.setUpdateByUid(null);
                entity.setRemark(null);
                entity.setSort(0);
                entity.setIsFromModel(0);
                entity.updateById();
            } catch (Exception e) {
            }
        }
        return list;
    }

}
